package ubi.quando.UI;

import java.util.List;

import org.osmdroid.util.GeoPoint;

import ubi.quando.App.Contact;
import ubi.quando.App.EventBase;
import ubi.quando.App.EventMeeting;
import ubi.quando.App.EventPickUp;
import ubi.quando.App.EventType;
import ubi.quando.App.PickUpParticipant;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.widget.Toast;

public class NotificationManager extends Service {

	public static boolean IS_RUNNING = false;

	private UbiApplication mApp;

	private LocationManager myLocationManager;
	private LocationListener myLocationListener;
	private GeoPoint mMyLocation;

	@Override
	public void onCreate() {
		super.onCreate();

		myLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		myLocationListener = new MyLocationListener();
		myLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
				0, 50, myLocationListener);
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public ComponentName startService(Intent service) {
		mApp = (UbiApplication) getApplication();

		mApp.setNotificationManager(this);
		IS_RUNNING = true;
		return super.startService(service);
	}

	@Override
	public boolean stopService(Intent name) {
		myLocationManager.removeUpdates(myLocationListener);
		myLocationManager = null;
		myLocationListener = null;
		IS_RUNNING = false;
		return super.stopService(name);
	}

	private class MyLocationListener implements LocationListener {

		public void onLocationChanged(Location loc) {
			mMyLocation = new GeoPoint(loc);

			if (mApp == null) {
				mApp = (UbiApplication) getApplication();
			}

			if (mApp.getCurrentActivity() instanceof EventRunningActivity) {
				EventRunningActivity activity = (EventRunningActivity) mApp
						.getCurrentActivity();
				activity.invalidateParticipants();
			}

			HandlePositionLogic();
		}

		public void onProviderDisabled(String provider) {
		}

		public void onProviderEnabled(String provider) {
		}

		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	};

	private void HandlePositionLogic() {
		String id = mApp.getId();
		mApp.getServerComm().updateGeo(id, /* event.getId(), */mMyLocation);

	}

	private void HandlePickupUpdate(EventPickUp event) {
		String pickerId = event.getPickerId();
		if (pickerId != null && pickerId.equals(mApp.getId())) {
			for(PickUpParticipant p : event.getParticipants())
			{
				GeoPoint loc = mApp.getContactById(p.getContact()).getLocation();  //TODO check it
				if (loc != null) {
					int distance = loc.distanceTo(p.getLocation());
					if (distance < 10) {
						MusicAlert.play(UbiApplication.CONTEXT,
								R.raw.meeting_arrival);
						Toast.makeText(
								UbiApplication.CONTEXT,
								event.GetName() + ": " + p.getName()
										+ " is waiting at pickup location!",
								Toast.LENGTH_LONG).show();
					}
					else if(distance < 500)
					{
						MusicAlert.play(UbiApplication.CONTEXT,
								R.raw.meeting_arrival);
						Toast.makeText(
								UbiApplication.CONTEXT,
								event.GetName() + ": " + p.getName()
										+ " is less than 500 meters from pickup location",
								Toast.LENGTH_LONG).show();
					}
				}
			}
		}
		else
		{
			PickUpParticipant me = null;
			Contact picker = mApp.getServerComm().getContact(event.getPickerId());
			if(picker != null)
			{
				for(PickUpParticipant p : event.getParticipants())
				{
					if(p.getContact()/*.getId()*/.equals(mApp.getId()))//TODO check it
					{
						me = p;
						break;
					}
				}
				
				GeoPoint loc = picker.getLocation();
				if (loc != null && me != null) {
					int distance = loc.distanceTo(me.getLocation());
					if (distance < 10) {
						MusicAlert.play(UbiApplication.CONTEXT,
								R.raw.meeting_arrival);
						Toast.makeText(
								UbiApplication.CONTEXT,
								event.GetName() + ": " + picker.getName()
										+ " is waiting at pickup location!",
								Toast.LENGTH_LONG).show();
					}
					else if(distance < 500)
					{
						MusicAlert.play(UbiApplication.CONTEXT,
								R.raw.meeting_arrival);
						Toast.makeText(
								UbiApplication.CONTEXT,
								event.GetName() + ": " + picker.getName()
										+ " is less than 500 meters from pickup location",
								Toast.LENGTH_LONG).show();
					}		
				}
			}
		}
	}
	
	private void HandleMeetingUpdate(EventMeeting event) {
		List<Contact> participants = event.getParticipants();
		GeoPoint dest = event.GetDestination();
		for (Contact c : participants) {
			GeoPoint loc = c.getLocation();
			if (loc != null) {
				int distance = loc.distanceTo(dest);
				if (distance < 10) {
					MusicAlert.play(UbiApplication.CONTEXT,
							R.raw.meeting_arrival);
					Toast.makeText(
							UbiApplication.CONTEXT,
							event.GetName() + ": " + c.getName()
									+ " is waiting at meeting place!",
							Toast.LENGTH_LONG).show();
				}
				else if(distance < 500)
				{
					MusicAlert.play(UbiApplication.CONTEXT,
							R.raw.meeting_arrival);
					Toast.makeText(
							UbiApplication.CONTEXT,
							event.GetName() + ": " + c.getName()
									+ " is less than 500 meters from the meeting",
							Toast.LENGTH_LONG).show();
				}
			}
		}

	}

	public GeoPoint getLocation() {
		return mMyLocation;
	}

	public void notifyEventStarted(EventBase event) {
		if (mApp == null) {
			mApp = (UbiApplication) getApplication();
		}

		// TODO: another alert
		MusicAlert.play(UbiApplication.CONTEXT, R.raw.meeting_arrival);
		Toast.makeText(UbiApplication.CONTEXT,
				event.GetName() + ": Has been started", Toast.LENGTH_LONG)
				.show();
	}

	public void onClientLocationChanged() {
		EventBase event = mApp.getShowedEvent();
		if(event != null)
		{
			if(event.getType() == EventType.MEETING)
			{
				HandleMeetingUpdate((EventMeeting)event);
			}
			else
			{
				HandlePickupUpdate((EventPickUp)event);
			}
		}
	}
}
